package com.fgchen.study.velocity.util;

import com.fgchen.study.velocity.entity.Column;
import com.fgchen.study.velocity.entity.Table;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;

import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Properties;

public class CodeGenerator {

    public static final String JDBC_URL = "jdbc:mysql://localhost:3306/tolm?useUnicode=true&characterEncoding=utf8";
    public static final String JDBC_USER = "root";
    public static final String JDBC_PASSWORD = "123456";

    public static final String DB_NAME = "tolm";
    public static final String DB_TABLE = "stf_mstr";
    public static final String PACKAGE_BASE = "com.sf.portal.tolm";

    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
    }

    public static Table loadTable(Connection conn, String dbName, String tableName) throws SQLException {
        Table retval = new Table();
        retval.setDb(dbName);
        retval.setName(tableName);
        retval.setColumns(new ArrayList<Column>());

        ResultSet crs = conn.getMetaData().getColumns(dbName, null, tableName, "%");
        while (crs.next()) {
            String name = crs.getString("COLUMN_NAME");
            String typeName = crs.getString("TYPE_NAME");
            String remarks = crs.getString("REMARKS");
            retval.getColumns().add(new Column(name, typeName, remarks));
        }
        crs.close();
        return retval;
    }

    public static VelocityEngine getVelocityEngine() {
        VelocityEngine ve = new VelocityEngine();
        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());

        Properties props = new Properties();
        props.setProperty(Velocity.ENCODING_DEFAULT, "UTF8");
        props.setProperty(Velocity.INPUT_ENCODING, "UTF8");
        props.setProperty(Velocity.OUTPUT_ENCODING, "UTF8");
        ve.init(props);

        return ve;
    }

    public static void main(String[] args) throws Exception {
        Connection conn = getConnection();
        Table table = loadTable(conn, DB_NAME, DB_TABLE);
        VelocityEngine velocityEngine = getVelocityEngine();
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("table", table);
        velocityContext.put("basePackage", PACKAGE_BASE);

        //gen entity
        Template tableToClassTemplate = velocityEngine.getTemplate("class.vm");
        File javaFile = new File("code" + "/" + PACKAGE_BASE.replace(".", "/") + "/domain", String.format("%s.java", table.getClassName()));
        if (!javaFile.exists()) {
            javaFile.getParentFile().mkdirs();
            javaFile.createNewFile();
        }
        FileWriter javaFileWriter = new FileWriter(javaFile);
        tableToClassTemplate.merge(velocityContext, javaFileWriter);
        javaFileWriter.close();

        //gen properties
        Template columnsToPropertiesTemplate = velocityEngine.getTemplate("properties.vm");
        File propsFile = new File("code" + "/" + PACKAGE_BASE.replace(".", "/") + "/domain", String.format("%s.properties", table.getClassName()));
        if (!propsFile.exists()) {
            propsFile.getParentFile().mkdirs();
            propsFile.createNewFile();
        }
        FileWriter propsFileWriter = new FileWriter(propsFile);
        columnsToPropertiesTemplate.merge(velocityContext, propsFileWriter);
        propsFileWriter.close();

        //gen dao
        Template classToDaoTemplate = velocityEngine.getTemplate("dao.vm");
        File daoFile = new File("code" + "/" + PACKAGE_BASE.replace(".", "/") + "/dao", String.format("I%sDao.java", table.getClassName()));
        if (!daoFile.exists()) {
            daoFile.getParentFile().mkdirs();
            daoFile.createNewFile();
        }
        FileWriter daoFileWriter = new FileWriter(daoFile);
        classToDaoTemplate.merge(velocityContext, daoFileWriter);
        daoFileWriter.close();

        //gen dao impl
        Template classToDaoImplTemplate = velocityEngine.getTemplate("dao-impl.vm");
        File daoImplFile = new File("code" + "/" + PACKAGE_BASE.replace(".", "/") + "/dao/impl", String.format("%sDao.java", table.getClassName()));
        if (!daoImplFile.exists()) {
            daoImplFile.getParentFile().mkdirs();
            daoImplFile.createNewFile();
        }
        FileWriter daoImplFileWriter = new FileWriter(daoImplFile);
        classToDaoImplTemplate.merge(velocityContext, daoImplFileWriter);
        daoImplFileWriter.close();

        //gen biz
        Template classToBizTemplate = velocityEngine.getTemplate("biz.vm");
        File bizFile = new File("code" + "/" + PACKAGE_BASE.replace(".", "/") + "/biz", String.format("I%sBiz.java", table.getClassName()));
        if (!bizFile.exists()) {
            bizFile.getParentFile().mkdirs();
            bizFile.createNewFile();
        }
        FileWriter bizFileWriter = new FileWriter(bizFile);
        classToBizTemplate.merge(velocityContext, bizFileWriter);
        bizFileWriter.close();

        //gen biz impl
        Template classToBizImplTemplate = velocityEngine.getTemplate("biz-impl.vm");
        File bizImplFile = new File("code" + "/" + PACKAGE_BASE.replace(".", "/") + "/biz/impl", String.format("%sBiz.java", table.getClassName()));
        if (!bizImplFile.exists()) {
            bizImplFile.getParentFile().mkdirs();
            bizImplFile.createNewFile();
        }
        FileWriter bizImplFileWriter = new FileWriter(bizImplFile);
        classToBizImplTemplate.merge(velocityContext, bizImplFileWriter);
        bizImplFileWriter.close();

        //gen action
        Template classToActionTemplate = velocityEngine.getTemplate("action.vm");
        File actionFile = new File("code" + "/" + PACKAGE_BASE.replace(".", "/") + "/action", String.format("%sAction.java", table.getClassName()));
        if (!actionFile.exists()) {
            actionFile.getParentFile().mkdirs();
            actionFile.createNewFile();
        }
        FileWriter actionFileWriter = new FileWriter(actionFile);
        classToActionTemplate.merge(velocityContext, actionFileWriter);
        actionFileWriter.close();

        //gen jsp
        Template classToJspTemplate = velocityEngine.getTemplate("jsp.vm");
        File jspFile = new File("code", String.format("%s.jsp", table.getClassName()));
        if (!jspFile.exists()) {
            jspFile.getParentFile().mkdirs();
            jspFile.createNewFile();
        }
        FileWriter jspFileWriter = new FileWriter(jspFile);
        classToJspTemplate.merge(velocityContext, jspFileWriter);
        jspFileWriter.close();

        conn.close();
    }

}
